package com.ruoyi.wxorali.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.nls.client.AccessToken;
import com.aliyun.imageaudit20191230.Client;
import com.aliyun.imageaudit20191230.models.ScanImageAdvanceRequest;
import com.aliyun.imageaudit20191230.models.ScanImageRequest;
import com.aliyun.imageaudit20191230.models.ScanImageResponse;
import com.aliyun.imageaudit20191230.models.ScanTextRequest;
import com.aliyun.tea.TeaModel;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.Common;
import com.aliyun.teautil.models.RuntimeOptions;
import com.ruoyi.common.redis.RedisCache;
import com.ruoyi.system.config.SystemConfig;
import com.ruoyi.wxorali.service.AliYunYuYinService;
import com.ruoyi.wxorali.service.WAVTestService;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.MultimediaInfo;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import com.alibaba.nls.client.protocol.NlsClient;
import com.alibaba.nls.client.protocol.OutputFormatEnum;
import com.alibaba.nls.client.protocol.SampleRateEnum;
import com.alibaba.nls.client.protocol.tts.SpeechSynthesizer;
import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerListener;
import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerResponse;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class AliYunYuYinServiceImpl  implements AliYunYuYinService {
	@Resource
	private WAVTestService wavTestService;
	private final RedisCache redisCache;
	private String appKey = "Pkv2RisuFpG3Nkab"; //女
	private String appKey2 = "YVAzNETIBcwvTKKl";//男
	private String accessToken = "8b35c24a20054d7fb4d30134e006042e";
	private static String keyId ="LTAI5tK1PAJLPu31gS3zqriG";
	private static String secret="7FNldIiuyEbVMh9V2dJpnyhVlVffK1";


	/**
	 * 支付宝token
	 */
	private static String token = null;

	private static String imgtoken = null;
	/**
	 * 记录超时时间
	 */
	private static Long jshi = (long) 20000;
	/**
	 * 记录上次时间获取token
	 */
	private static Date date = null;

	public static String getToken() {
		if (ObjectUtils.isNotEmpty(token) && ObjectUtils.isNotEmpty(date) && date.getTime() + jshi > System.currentTimeMillis()) {
			return token;
		} else {
			AccessToken accToken = new AccessToken(keyId, secret);
			try {
				accToken.apply();
				System.out.println("get token: " + accToken.getToken() + ", expire time: " + accToken.getExpireTime());
				token = accToken.getToken();
				jshi = accToken.getExpireTime() - 20000;
				date = new Date();
			} catch (IOException e) {
				e.printStackTrace();
			}

			return token;
		}
	}
	@Override
	public JSONObject importTxt(File dstFile) throws IOException {
		JSONObject obj = new JSONObject();
		BufferedReader br = null;
		FileInputStream fis = null;
		InputStreamReader reader = null;
		String resourceRoot = SystemConfig.getUploadDir();
		try {
			SimpleDateFormat f = new SimpleDateFormat("yyyyMMddHHmmss");
			fis = new FileInputStream(dstFile);
			reader = new InputStreamReader(fis, "GBK");
			reader = new InputStreamReader(fis, "UTF-8");
			br = new BufferedReader(reader);
			char[] tempbytes = new char[300];
			int byteread = 0;
			StringBuffer sbIns = new StringBuffer();
			List<String> list = new ArrayList<String>();
			while ((byteread = br.read(tempbytes)) != -1) {
				sbIns.append(new String(tempbytes, 0, byteread));
				String name = "/upload/" + f.format(new Date()) + ".wav";
				String dstPath = resourceRoot + name;
				this.process(sbIns.toString(), dstPath);
				sbIns.delete(0, sbIns.length());
				list.add(name);
			}
			obj.put("url", list);
			obj.put("iden", true);
			reader.close();
			fis.close();
			br.close();
			return obj;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			obj.put("iden", false);
			return obj;
		} catch (IOException e) {
			e.printStackTrace();
			obj.put("iden", false);
			return obj;
		} finally {

			reader.close();
			fis.close();
			br.close();
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

		}
	}

	@Override
	public List<String> heBingYuYin(List<String> list) throws IOException {
		boolean iden = false;
		List<String> saveUrls = new ArrayList<>();
		SimpleDateFormat f = new SimpleDateFormat("yyyyMMddHHmmssS");
		String resourceRoot = SystemConfig.getUploadDir();
		String name = null;
		if (list.size() > 1) {
			int jishu = 0;
			int number = 0;
			String file = null;
			String fileT = null;
			for (String url:list ) {
				jishu++;
				number++;
				if (jishu == 1) {
					file = url;
				}
				if (jishu == 2) {

					fileT = url;
					Long chang = getDuration(new File(resourceRoot + file));
					Long changT = getDuration(new File(resourceRoot + fileT));
					if (chang > 10 && changT > 10) {
						saveUrls.add(file);
						saveUrls.add(fileT);
						jishu = 0;
					} else if (chang > 10 && changT < 10) {
						saveUrls.add(file);
						file =  fileT;
						jishu = 1;
					} else {
						name = "/upload/" + f.format(new Date()) + ".wav";
						iden = wavTestService.addWav(file, fileT, name);
						if (iden) {
							Long changN = getDuration(new File(resourceRoot + name));
							if (changN > 10) {
								saveUrls.add(name);
								jishu = 0;
							} else {
								if(number == list.size()){
									saveUrls.add(name);
								}else{
									file = name;
									jishu = 1;
								}

							}

						}
					}
					continue;
				}
				if (jishu == 1 && number == list.size()) {
					if(saveUrls.size() > 0){
						Long changN = getDuration(new File(resourceRoot + file));
					if(changN < 6){
							name = "/upload/" + f.format(new Date()) + ".wav";
							iden = wavTestService.addWav(saveUrls.get(saveUrls.size()-1), file, name);
							if(iden){
								saveUrls.remove(saveUrls.size()-1);
								saveUrls.add(name);
							}
						}else{
						saveUrls.add(file);
					}

					}else{
						saveUrls.add(file);
					}

				}
			}
		}else{
			return list;
		}
		return saveUrls;
	}

	@Override
	/**
	 * base64字符串转换成图片
	 * @param imgStr		base64字符串
	 * @param imgFilePath	图片存放路径
	 * @return
	 *
	 * @author ZHANGJL
	 * @dateTime 2018-02-23 14:42:17
	 */
	public String getPhoto(HttpServletRequest request,String Picurl) { // 对字节数组字符串进行Base64解码并生成图片
		SimpleDateFormat sdfo = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		String resourceRoot = SystemConfig.getUploadDir();
		String dateo=sdfo.format(new Date());
		String filename ="/uploadPhoto/" +dateo + ".jpg";
		String imgFilePath=resourceRoot+filename;
		String filepath=resourceRoot+"/uploadPhoto";
		File fileo=new File(filepath);
		if(!fileo.exists()){//如果文件夹不存在
			fileo.mkdir();//创建文件夹
		}
		Date date = new Date(System.currentTimeMillis() - 1000 * 60);
		File folder = new File(filepath);
		File[] files = folder.listFiles();
		for (int i=0;i<files.length;i++){
			File file = files[i];
			if (new Date(file.lastModified()).before(date)){
				file.delete();
			}
		}
		URL url = null;
		try {
			url = new URL(Picurl);
			DataInputStream dataInputStream = new DataInputStream(url.openStream());
			File file3=new File(imgFilePath);
			if (!file3.exists()) {
				file3.createNewFile();
			}
			FileOutputStream fileOutputStream = new FileOutputStream(file3);
			ByteArrayOutputStream output = new ByteArrayOutputStream();

			byte[] buffer = new byte[1024];
			int length;

			while ((length = dataInputStream.read(buffer)) > 0) {
				output.write(buffer, 0, length);
			}
			fileOutputStream.write(output.toByteArray());
			dataInputStream.close();
			fileOutputStream.close();

		} catch (MalformedURLException e) {
			e.printStackTrace();

		} catch (IOException e) {
			e.printStackTrace();

		}
		return filename;

	}

	/**
		 * 音频文件获取文件时长
		 * @param source
		 * @return
		 */
		public  Long getDuration(File source) {

			Encoder encoder = new Encoder();
			long ls = 0;
			MultimediaInfo m;
			try {
				m = encoder.getInfo(source);
				ls = m.getDuration()/1000/60;
			} catch (Exception e) {
				System.out.println("获取音频时长有误：" + e.getMessage());
			}
			return ls;
		}

		/**
		 * 递归删除目录下的所有文件及子目录下所有文件
		 * @param dir 将要删除的文件目录
		 * @return boolean Returns "true" if all deletions were successful.
		 *                 If a deletion fails, the method stops attempting to
		 *                 delete and returns "false".
		 */
		private  boolean deleteDir(File dir) {
			if (dir.isDirectory()) {
				String[] children = dir.list();
				//递归删除目录中的子目录下
				for (int i=0; i<children.length; i++) {
					boolean success = deleteDir(new File(dir, children[i]));
					if (!success) {
						return false;
					}
				}
			}
			// 目录此时为空，可以删除
			return dir.delete();
		}
		// Step0 创建NlsClient实例,应用全局创建一个即可,默认服务地址为阿里云线上服务地址

		private  SpeechSynthesizerListener getSynthesizerListener(final String str) {
			SpeechSynthesizerListener listener = null;
			try {
				listener = new SpeechSynthesizerListener() {
					File f = new File(str);
					FileOutputStream fout = new FileOutputStream(f);
					// 语音合成结束
					@Override
					public void onComplete(SpeechSynthesizerResponse response) {
						// 事件名称 SynthesisCompleted
						System.out.println("name: " + response.getName() +
								// 状态码 20000000 表示识别成功
								", status: " + response.getStatus() +
								// 语音合成文件路径
								", output file :"+ f.getAbsolutePath()
						);
					}

					@Override
					public void onFail(SpeechSynthesizerResponse speechSynthesizerResponse) {

					}



					// 语音合成的语音二进制数据
					@Override
					public void onMessage(ByteBuffer message) {
						try {
							byte[] bytesArray = new byte[message.remaining()];
							message.get(bytesArray, 0, bytesArray.length);
							//System.out.println("write array:" + bytesArray.length);
							fout.write(bytesArray);
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				};

			} catch (Exception e) {
				e.printStackTrace();
			}
			return listener;
		}
		public String process(String zifu,String str) {
			accessToken= getToken();
			if(ObjectUtils.isEmpty(accessToken)){
				System.out.println( "获取token失败-----------------------------------------");
				return null;
			}
			NlsClient client = new NlsClient(accessToken);
			SpeechSynthesizer synthesizer = null;
			try {
				// Step1 创建实例,建立连接
				synthesizer = new SpeechSynthesizer(client, getSynthesizerListener(str));
				synthesizer.setAppKey(appKey2);
				// 设置返回音频的编码格式
				synthesizer.setFormat(OutputFormatEnum.WAV);
				// 设置返回音频的采样率
				synthesizer.setSampleRate(SampleRateEnum.SAMPLE_RATE_16K);
				// 设置用于语音合成的文本
				synthesizer.setText(zifu);
				// Step2 此方法将以上参数设置序列化为json发送给服务端,并等待服务端确认
				synthesizer.start();
				// Step3 等待语音合成结束
				synthesizer.waitForComplete();
			} catch (Exception e) {
				System.err.println(e.getMessage());
			} finally {

				// Step4 关闭连接
				if (null != synthesizer) {
					synthesizer.close();
				}
				client.shutdown();


			}

			return accessToken;
		}
	public Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        /*
          初始化配置对象com.aliyun.teaopenapi.models.Config
          Config对象存放AccessKeyId、AccessKeySecret、endpoint等配置
         */
		Config config = new Config()
				.setAccessKeyId(accessKeyId)
				.setAccessKeySecret(accessKeySecret);
		// 访问的域名
		config.endpoint = "imageaudit.cn-shanghai.aliyuncs.com";
		return new Client(config);
	}
	@Override
	public JSONArray generateImage(List<File>list) throws Exception {
		// 创建AccessKey ID和AccessKey Secret，请参考https://help.aliyun.com/document_detail/175144.html
		// 如果您使用的是RAM用户的AccessKey，还需要为子账号授予权限AliyunVIAPIFullAccess，请参考https://help.aliyun.com/document_detail/145025.html
		// 从环境变量读取配置的AccessKey ID和AccessKey Secret。运行代码示例前必须先配置环境变量。
		String accessKeyId = System.getenv(keyId);
		String accessKeySecret = System.getenv(secret);
		Client client = this.createClient(keyId, secret);
		List<ScanImageAdvanceRequest.ScanImageAdvanceRequestTask> taskList = new ArrayList<>();
		for (File file:list) {
			InputStream inputStream = new FileInputStream(file);
			ScanImageAdvanceRequest.ScanImageAdvanceRequestTask task0 = new ScanImageAdvanceRequest.ScanImageAdvanceRequestTask();
			task0.setDataId(file.getName());
			task0.setImageTimeMillisecond(1L);
			task0.setInterval(1);
			task0.setMaxFrames(1);
			task0.setImageURLObject(inputStream);
			taskList.add(task0);
		}
		List<String> sceneList = new ArrayList<>();
		sceneList.add("porn");
		ScanImageAdvanceRequest scanImageAdvanceRequest = new ScanImageAdvanceRequest()
				.setTask(taskList)
				.setScene(sceneList);
		RuntimeOptions runtime = new RuntimeOptions();
		try {
			ScanImageResponse scanImageResponse = client.scanImageAdvance(scanImageAdvanceRequest, runtime);
			// 获取整体结果
		//	System.out.println(Common.toJSONString(TeaModel.buildMap(scanImageResponse)));
			// 获取单个字段
			return JSONArray.fromObject(scanImageResponse.getBody().getData());
		} catch (com.aliyun.tea.TeaException teaException) {
			// 获取整体报错信息
			System.out.println(com.aliyun.teautil.Common.toJSONString(teaException));
			// 获取单个字段
			System.out.println(teaException.getCode());
		}
		return new JSONArray();
	}

	}

